﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ApiDoc
{
    partial class ApiDocumentationManager
    {
        /// <summary>
        /// Returns the TypeDocumentation for <paramref name="type"/>.
        /// </summary>
        /// <remarks>
        /// If the assembly containing <paramref name="type"/> is not already part of the documentation managed by this manager
        /// it will be added with AddAssembly() before generating the documentation for <paramref name="type"/>.
        /// </remarks>
        /// <param name="type"></param>
        /// <returns></returns>
        public TypeDocumentation GetTypeDocumentation(Type type)
        {
            string cref = CRef.ReflectionCRefGenerator.NoPrefix.GetCRef(type);

            // Try the cache first.
            if (m_types.ContainsKey(cref)) {
                return m_types[cref];
            }

            // Add the assembly for the type we don't already have it included.
            if (!m_assemblies.Contains(type.Assembly)) {
                AddAssembly(type.Assembly);
            }

            // Cache the result using the type directly.
            var ret = new TypeDocumentation(type, this);

            m_types.Add(cref, ret);

            return ret;
        }

        /// <summary>
        /// Returns the TypeDocumentation for <paramref name="cref"/>.
        /// </summary>
        /// <param name="cref"></param>
        /// <returns></returns>
        public TypeDocumentation GetTypeDocumentation(string cref)
        {
            // If we have it in the cache then use it.
            if (m_types.ContainsKey(cref)) {
                return m_types[cref];
            }

            Type type = null;
            foreach (var assembly in m_assemblies) {
                type = CRef.ReflectionCRefLookup.GetMemberInfo(assembly, new CRef.CRefIdentifier(cref)) as Type;
                if (type != null) {
                    break;
                }
            }

            if (type == null) {
                return null; ;
            }

            // Cache the result.
            var ret = new TypeDocumentation(type, this);
            m_types.Add(type.FullName, ret);

            return ret;
        }

        private Dictionary<string, TypeDocumentation> m_types = new Dictionary<string, TypeDocumentation>();
    }
}
